import 'dart:async';
import 'dart:convert';

import 'package:backend.analytics/domain/entities/amplitude_api/amplitude_api_event.dart';
import 'package:backend.analytics/domain/entities/amplitude_api/amplitude_api_event_type.dart';
import 'package:backend.analytics/domain/services/amplitude_api_service/service.dart';
import 'package:built_collection/built_collection.dart';
import 'package:backend.core/core/domain/config/config.dart';
import 'package:backend.core/logger/logger.dart';
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:http/http.dart' as http;

part 'dtos/event_dto.dart';

part 'dtos/event_type_dto.dart';

part 'dtos/time_dto.dart';

class AmplitudeApiServiceImpl implements AmplitudeApiService {
  const AmplitudeApiServiceImpl({
    required http.Client httpClient,
  })  : _httpClient = httpClient;

  final http.Client _httpClient;

  @override
  Future<Either<AmplitudeApiEventSendingFailure, void>> sendEvents({
    required BuiltList<AmplitudeApiEvent> events,
  }) async {
    final eventJsons = events.map((event) {
      return _EventDto.fromEntity(event).toJson();
    }).toList();

    final payload = {
      'api_key': Config().amplitudeApiKey,
      'events': eventJsons,
    };

    final requestBody = jsonEncode(payload);

    final url = Uri.parse('https://api2.amplitude.com/2/httpapi');

    const headers = {
      'Content-Type': 'application/json',
      'Accept': '*/*',
    };

    final http.Response response;

    try {
      response = await _httpClient.post(
        url,
        body: requestBody,
        headers: headers,
      );
    } catch (e, s) {
      Logger().w(null, e, s);
      const failure = AmplitudeApiEventSendingFailure();
      return left(failure);
    }

    if (response.statusCode != 200) {
      Logger().w(null, response.body, StackTrace.current);
      const failure = AmplitudeApiEventSendingFailure();
      return left(failure);
    }

    return right(null);
  }
}
